home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / Mesa-3.0 / SRC / TEXIMAGE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-09-18  |  77.4 KB  |  2,407 lines

  1. /* $Id: teximage.c,v 3.12 1998/09/18 02:32:40 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.0
  6.  * Copyright (C) 1995-1998  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: teximage.c,v $
  26.  * Revision 3.12  1998/09/18 02:32:40  brianp
  27.  * fixed proxy texture internal format bug reported by Sam Jordon
  28.  *
  29.  * Revision 3.11  1998/07/18 03:35:01  brianp
  30.  * fixed a few error reporting mistakes
  31.  *
  32.  * Revision 3.10  1998/07/17 03:25:17  brianp
  33.  * implemented glGetTexImage()
  34.  *
  35.  * Revision 3.9  1998/05/05 00:28:52  brianp
  36.  * GL_ABGR_EXT pixel format now works with glTexImageXD()
  37.  *
  38.  * Revision 3.8  1998/05/05 00:19:47  brianp
  39.  * added GL_COLOR_INDEX to cases in components_in_intformat
  40.  *
  41.  * Revision 3.7  1998/04/20 21:46:08  brianp
  42.  * added David's second glCopyTexSubImage() patch
  43.  *
  44.  * Revision 3.6  1998/04/13 23:16:57  brianp
  45.  * fixed 3Dfx glCopyTexSubImage() bug (David Bucciarelli)
  46.  *
  47.  * Revision 3.5  1998/03/27 04:17:31  brianp
  48.  * fixed G++ warnings
  49.  *
  50.  * Revision 3.4  1998/03/03 02:42:38  brianp
  51.  * removed a few unneeded assertions
  52.  *
  53.  * Revision 3.3  1998/02/20 04:53:37  brianp
  54.  * implemented GL_SGIS_multitexture
  55.  *
  56.  * Revision 3.2  1998/02/07 14:42:29  brianp
  57.  * NULL proxy image given to glTexImageXD() caused crash (Wes Bethel)
  58.  *
  59.  * Revision 3.1  1998/02/01 22:28:41  brianp
  60.  * removed an unneeded header
  61.  *
  62.  * Revision 3.0  1998/01/31 21:04:38  brianp
  63.  * initial rev
  64.  *
  65.  */
  66.  
  67.  
  68. #ifdef PC_HEADER
  69. #include "all.h"
  70. #else
  71. #include <assert.h>
  72. #include <stdio.h>
  73. #include <stdlib.h>
  74. #include <string.h>
  75. #include "context.h"
  76. #include "image.h"
  77. #include "macros.h"
  78. #include "span.h"
  79. #include "teximage.h"
  80. #include "types.h"
  81. #endif
  82.  
  83.  
  84. /*
  85.  * NOTES:
  86.  *
  87.  * The internal texture storage convension is an array of N GLubytes
  88.  * where N = width * height * components.  There is no padding.
  89.  */
  90.  
  91.  
  92.  
  93.  
  94. /*
  95.  * Compute log base 2 of n.
  96.  * If n isn't an exact power of two return -1.
  97.  * If n<0 return -1.
  98.  */
  99. static int logbase2( int n )
  100. {
  101.    GLint i = 1;
  102.    GLint log2 = 0;
  103.  
  104.    if (n<0) {
  105.       return -1;
  106.    }
  107.  
  108.    while ( n > i ) {
  109.       i *= 2;
  110.       log2++;
  111.    }
  112.    if (i != n) {
  113.       return -1;
  114.    }
  115.    else {
  116.       return log2;
  117.    }
  118. }
  119.  
  120.  
  121.  
  122. /*
  123.  * Given an internal texture format enum or 1, 2, 3, 4 return the
  124.  * corresponding _base_ internal format:  GL_ALPHA, GL_LUMINANCE,
  125.  * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.  Return -1 if
  126.  * invalid enum.
  127.  */
  128. static GLint decode_internal_format( GLint format )
  129. {
  130.    switch (format) {
  131.       case GL_ALPHA:
  132.       case GL_ALPHA4:
  133.       case GL_ALPHA8:
  134.       case GL_ALPHA12:
  135.       case GL_ALPHA16:
  136.          return GL_ALPHA;
  137.       case 1:
  138.       case GL_LUMINANCE:
  139.       case GL_LUMINANCE4:
  140.       case GL_LUMINANCE8:
  141.       case GL_LUMINANCE12:
  142.       case GL_LUMINANCE16:
  143.          return GL_LUMINANCE;
  144.       case 2:
  145.       case GL_LUMINANCE_ALPHA:
  146.       case GL_LUMINANCE4_ALPHA4:
  147.       case GL_LUMINANCE6_ALPHA2:
  148.       case GL_LUMINANCE8_ALPHA8:
  149.       case GL_LUMINANCE12_ALPHA4:
  150.       case GL_LUMINANCE12_ALPHA12:
  151.       case GL_LUMINANCE16_ALPHA16:
  152.          return GL_LUMINANCE_ALPHA;
  153.       case GL_INTENSITY:
  154.       case GL_INTENSITY4:
  155.       case GL_INTENSITY8:
  156.       case GL_INTENSITY12:
  157.       case GL_INTENSITY16:
  158.          return GL_INTENSITY;
  159.       case 3:
  160.       case GL_RGB:
  161.       case GL_R3_G3_B2:
  162.       case GL_RGB4:
  163.       case GL_RGB5:
  164.       case GL_RGB8:
  165.       case GL_RGB10:
  166.       case GL_RGB12:
  167.       case GL_RGB16:
  168.          return GL_RGB;
  169.       case 4:
  170.       case GL_RGBA:
  171.       case GL_RGBA2:
  172.       case GL_RGBA4:
  173.       case GL_RGB5_A1:
  174.       case GL_RGBA8:
  175.       case GL_RGB10_A2:
  176.       case GL_RGBA12:
  177.       case GL_RGBA16:
  178.          return GL_RGBA;
  179.       case GL_COLOR_INDEX1_EXT:
  180.       case GL_COLOR_INDEX2_EXT:
  181.       case GL_COLOR_INDEX4_EXT:
  182.       case GL_COLOR_INDEX8_EXT:
  183.       case GL_COLOR_INDEX12_EXT:
  184.       case GL_COLOR_INDEX16_EXT:
  185.          return GL_COLOR_INDEX;
  186.       default:
  187.          return -1;  /* error */
  188.    }
  189. }
  190.  
  191.  
  192.  
  193. /*
  194.  * Given an internal texture format enum or 1, 2, 3, 4 return the
  195.  * corresponding _base_ internal format:  GL_ALPHA, GL_LUMINANCE,
  196.  * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.  Return the
  197.  * number of components for the format.  Return -1 if invalid enum.
  198.  */
  199. static GLint components_in_intformat( GLint format )
  200. {
  201.    switch (format) {
  202.       case GL_ALPHA:
  203.       case GL_ALPHA4:
  204.       case GL_ALPHA8:
  205.       case GL_ALPHA12:
  206.       case GL_ALPHA16:
  207.          return 1;
  208.       case 1:
  209.       case GL_LUMINANCE:
  210.       case GL_LUMINANCE4:
  211.       case GL_LUMINANCE8:
  212.       case GL_LUMINANCE12:
  213.       case GL_LUMINANCE16:
  214.          return 1;
  215.       case 2:
  216.       case GL_LUMINANCE_ALPHA:
  217.       case GL_LUMINANCE4_ALPHA4:
  218.       case GL_LUMINANCE6_ALPHA2:
  219.       case GL_LUMINANCE8_ALPHA8:
  220.       case GL_LUMINANCE12_ALPHA4:
  221.       case GL_LUMINANCE12_ALPHA12:
  222.       case GL_LUMINANCE16_ALPHA16:
  223.          return 2;
  224.       case GL_INTENSITY:
  225.       case GL_INTENSITY4:
  226.       case GL_INTENSITY8:
  227.       case GL_INTENSITY12:
  228.       case GL_INTENSITY16:
  229.          return 1;
  230.       case 3:
  231.       case GL_RGB:
  232.       case GL_R3_G3_B2:
  233.       case GL_RGB4:
  234.       case GL_RGB5:
  235.       case GL_RGB8:
  236.       case GL_RGB10:
  237.       case GL_RGB12:
  238.       case GL_RGB16:
  239.          return 3;
  240.       case 4:
  241.       case GL_RGBA:
  242.       case GL_RGBA2:
  243.       case GL_RGBA4:
  244.       case GL_RGB5_A1:
  245.       case GL_RGBA8:
  246.       case GL_RGB10_A2:
  247.       case GL_RGBA12:
  248.       case GL_RGBA16:
  249.          return 4;
  250.       case GL_COLOR_INDEX:
  251.       case GL_COLOR_INDEX1_EXT:
  252.       case GL_COLOR_INDEX2_EXT:
  253.       case GL_COLOR_INDEX4_EXT:
  254.       case GL_COLOR_INDEX8_EXT:
  255.       case GL_COLOR_INDEX12_EXT:
  256.       case GL_COLOR_INDEX16_EXT:
  257.          return 1;
  258.       default:
  259.          return -1;  /* error */
  260.    }
  261. }
  262.  
  263.  
  264.  
  265. struct gl_texture_image *gl_alloc_texture_image( void )
  266. {
  267.    return (struct gl_texture_image *) calloc( 1, sizeof(struct gl_texture_image) );
  268. }
  269.  
  270.  
  271.  
  272. void gl_free_texture_image( struct gl_texture_image *teximage )
  273. {
  274.    if (teximage->Data) {
  275.       free( teximage->Data );
  276.    }
  277.    free( teximage );
  278. }
  279.  
  280.  
  281.  
  282. /*
  283.  * Given a gl_image, apply the pixel transfer scale, bias, and mapping
  284.  * to produce a gl_texture_image.  Convert image data to GLubytes.
  285.  * Input:  image - the incoming gl_image
  286.  *         internalFormat - desired format of resultant texture
  287.  *         border - texture border width (0 or 1)
  288.  * Return:  pointer to a gl_texture_image or NULL if an error occurs.
  289.  */
  290. static struct gl_texture_image *
  291. image_to_texture( GLcontext *ctx, const struct gl_image *image,
  292.                   GLint internalFormat, GLint border )
  293. {
  294.    GLint components;
  295.    struct gl_texture_image *texImage;
  296.    GLint numPixels, pixel;
  297.    GLboolean scaleOrBias;
  298.  
  299.    assert(image);
  300.    assert(image->Width>0);
  301.    assert(image->Height>0);
  302.    assert(image->Depth>0);
  303.  
  304.    /*   internalFormat = decode_internal_format(internalFormat);*/
  305.    components = components_in_intformat(internalFormat);
  306.    numPixels = image->Width * image->Height * image->Depth;
  307.  
  308.    texImage = gl_alloc_texture_image();
  309.    if (!texImage)
  310.       return NULL;
  311.  
  312.    texImage->Format = (GLenum) decode_internal_format(internalFormat);
  313.    texImage->IntFormat = (GLenum) internalFormat;
  314.    texImage->Border = border;
  315.    texImage->Width = image->Width;
  316.    texImage->Height = image->Height;
  317.    texImage->Depth = image->Depth;
  318.    texImage->WidthLog2 = logbase2(image->Width - 2*border);
  319.    if (image->Height==1)  /* 1-D texture */
  320.       texImage->HeightLog2 = 0;
  321.    else
  322.       texImage->HeightLog2 = logbase2(image->Height - 2*border);
  323.    if (image->Depth==1)   /* 2-D texture */
  324.       texImage->DepthLog2 = 0;
  325.    else
  326.       texImage->DepthLog2 = logbase2(image->Depth - 2*border);
  327.    texImage->Width2 = 1 << texImage->WidthLog2;
  328.    texImage->Height2 = 1 << texImage->HeightLog2;
  329.    texImage->Depth2 = 1 << texImage->DepthLog2;
  330.    texImage->MaxLog2 = MAX2( texImage->WidthLog2, texImage->HeightLog2 );
  331.    texImage->Data = (GLubyte *) malloc( numPixels * components );
  332.  
  333.    if (!texImage->Data) {
  334.       /* out of memory */
  335.       gl_free_texture_image( texImage );
  336.       return NULL;
  337.    }
  338.  
  339.    /* Determine if scaling and/or biasing is needed */
  340.    if (ctx->Pixel.RedScale!=1.0F   || ctx->Pixel.RedBias!=0.0F ||
  341.        ctx->Pixel.GreenScale!=1.0F || ctx->Pixel.GreenBias!=0.0F ||
  342.        ctx->Pixel.BlueScale!=1.0F  || ctx->Pixel.BlueBias!=0.0F ||
  343.        ctx->Pixel.AlphaScale!=1.0F || ctx->Pixel.AlphaBias!=0.0F) {
  344.       scaleOrBias = GL_TRUE;
  345.    }
  346.    else {
  347.       scaleOrBias = GL_FALSE;
  348.    }
  349.  
  350.    switch (image->Type) {
  351.       case GL_BITMAP:
  352.          {
  353.             GLint shift = ctx->Pixel.IndexShift;
  354.             GLint offset = ctx->Pixel.IndexOffset;
  355.             /* MapIto[RGBA]Size must be powers of two */
  356.             GLint rMask = ctx->Pixel.MapItoRsize-1;
  357.             GLint gMask = ctx->Pixel.MapItoGsize-1;
  358.             GLint bMask = ctx->Pixel.MapItoBsize-1;
  359.             GLint aMask = ctx->Pixel.MapItoAsize-1;
  360.             GLint i, j;
  361.             GLubyte *srcPtr = (GLubyte *) image->Data;
  362.  
  363.             assert( image->Format==GL_COLOR_INDEX );
  364.  
  365.             for (j=0; j<image->Height; j++) {
  366.                GLubyte bitMask = 128;
  367.                for (i=0; i<image->Width; i++) {
  368.                   GLint index;
  369.                   GLubyte red, green, blue, alpha;
  370.  
  371.                   /* Fetch image color index */
  372.                   index = (*srcPtr & bitMask) ? 1 : 0;
  373.                   bitMask = bitMask >> 1;
  374.                   if (bitMask==0) {
  375.                      bitMask = 128;
  376.                      srcPtr++;
  377.                   }
  378.                   /* apply index shift and offset */
  379.                   if (shift>=0) {
  380.                      index = (index << shift) + offset;
  381.                   }
  382.                   else {
  383.                      index = (index >> -shift) + offset;
  384.                   }
  385.                   /* convert index to RGBA */
  386.                   red   = (GLint) (ctx->Pixel.MapItoR[index & rMask] * 255.0F);
  387.                   green = (GLint) (ctx->Pixel.MapItoG[index & gMask] * 255.0F);
  388.                   blue  = (GLint) (ctx->Pixel.MapItoB[index & bMask] * 255.0F);
  389.                   alpha = (GLint) (ctx->Pixel.MapItoA[index & aMask] * 255.0F);
  390.  
  391.                   /* store texel (components are GLubytes in [0,255]) */
  392.                   pixel = j * image->Width + i;
  393.                   switch (texImage->Format) {
  394.                      case GL_ALPHA:
  395.                         texImage->Data[pixel] = alpha;
  396.                         break;
  397.                      case GL_LUMINANCE:
  398.                         texImage->Data[pixel] = red;
  399.                         break;
  400.                      case GL_LUMINANCE_ALPHA:
  401.                         texImage->Data[pixel*2+0] = red;
  402.                         texImage->Data[pixel*2+1] = alpha;
  403.                         break;
  404.                      case GL_INTENSITY:
  405.                         texImage->Data[pixel] = red;
  406.                         break;
  407.                      case GL_RGB:
  408.                         texImage->Data[pixel*3+0] = red;
  409.                         texImage->Data[pixel*3+1] = green;
  410.                         texImage->Data[pixel*3+2] = blue;
  411.                         break;
  412.                      case GL_RGBA:
  413.                         texImage->Data[pixel*4+0] = red;
  414.                         texImage->Data[pixel*4+1] = green;
  415.                         texImage->Data[pixel*4+2] = blue;
  416.                         texImage->Data[pixel*4+3] = alpha;
  417.                         break;
  418.                      default:
  419.                         gl_problem(ctx,"Bad format in image_to_texture");
  420.                         return NULL;
  421.                   }
  422.                }
  423.                if (bitMask!=128) {
  424.                   srcPtr++;
  425.                }
  426.             }
  427.          }
  428.          break;
  429.  
  430.       case GL_UNSIGNED_BYTE:
  431.          for (pixel=0; pixel<numPixels; pixel++) {
  432.             GLubyte red, green, blue, alpha;
  433.             switch (image->Format) {
  434.                case GL_COLOR_INDEX:
  435.                   if (decode_internal_format(internalFormat)==GL_COLOR_INDEX) {
  436.                      /* a paletted texture */
  437.                      GLint index = ((GLubyte*)image->Data)[pixel];
  438.                      red = index;
  439.                   }
  440.                   else {
  441.                      /* convert color index to RGBA */
  442.                      GLint index = ((GLubyte*)image->Data)[pixel];
  443.                      red   = (GLint) (255.0F * ctx->Pixel.MapItoR[index]);
  444.                      green = (GLint) (255.0F * ctx->Pixel.MapItoG[index]);
  445.                      blue  = (GLint) (255.0F * ctx->Pixel.MapItoB[index]);
  446.                      alpha = (GLint) (255.0F * ctx->Pixel.MapItoA[index]);
  447.                   }
  448.                   break;
  449.                case GL_RGB:
  450.                   /* Fetch image RGBA values */
  451.                   red   = ((GLubyte*) image->Data)[pixel*3+0];
  452.                   green = ((GLubyte*) image->Data)[pixel*3+1];
  453.                   blue  = ((GLubyte*) image->Data)[pixel*3+2];
  454.                   alpha = 255;
  455.                   break;
  456.                case GL_RGBA:
  457.                   red   = ((GLubyte*) image->Data)[pixel*4+0];
  458.                   green = ((GLubyte*) image->Data)[pixel*4+1];
  459.                   blue  = ((GLubyte*) image->Data)[pixel*4+2];
  460.                   alpha = ((GLubyte*) image->Data)[pixel*4+3];
  461.                   break;
  462.                case GL_RED:
  463.                   red   = ((GLubyte*) image->Data)[pixel];
  464.                   green = 0;
  465.                   blue  = 0;
  466.                   alpha = 255;
  467.                   break;
  468.                case GL_GREEN:
  469.                   red   = 0;
  470.                   green = ((GLubyte*) image->Data)[pixel];
  471.                   blue  = 0;
  472.                   alpha = 255;
  473.                   break;
  474.                case GL_BLUE:
  475.                   red   = 0;
  476.                   green = 0;
  477.                   blue  = ((GLubyte*) image->Data)[pixel];
  478.                   alpha = 255;
  479.                   break;
  480.                case GL_ALPHA:
  481.                   red   = 0;
  482.                   green = 0;
  483.                   blue  = 0;
  484.                   alpha = ((GLubyte*) image->Data)[pixel];
  485.                   break;
  486.                case GL_LUMINANCE: 
  487.                   red   = ((GLubyte*) image->Data)[pixel];
  488.                   green = red;
  489.                   blue  = red;
  490.                   alpha = 255;
  491.                   break;
  492.               case GL_LUMINANCE_ALPHA:
  493.                   red   = ((GLubyte*) image->Data)[pixel*2+0];
  494.                   green = red;
  495.                   blue  = red;
  496.                   alpha = ((GLubyte*) image->Data)[pixel*2+1];
  497.                   break;
  498.               default:
  499.                  gl_problem(ctx,"Bad format (2) in image_to_texture");
  500.                  return NULL;
  501.             }
  502.             
  503.             if (scaleOrBias || ctx->Pixel.MapColorFlag) {
  504.                /* Apply RGBA scale and bias */
  505.                GLfloat r = red   * (1.0F/255.0F);
  506.                GLfloat g = green * (1.0F/255.0F);
  507.                GLfloat b = blue  * (1.0F/255.0F);
  508.                GLfloat a = alpha * (1.0F/255.0F);
  509.                if (scaleOrBias) {
  510.                   /* r,g,b,a now in [0,1] */
  511.                   r = r * ctx->Pixel.RedScale   + ctx->Pixel.RedBias;
  512.                   g = g * ctx->Pixel.GreenScale + ctx->Pixel.GreenBias;
  513.                   b = b * ctx->Pixel.BlueScale  + ctx->Pixel.BlueBias;
  514.                   a = a * ctx->Pixel.AlphaScale + ctx->Pixel.AlphaBias;
  515.                   r = CLAMP( r, 0.0F, 1.0F );
  516.                   g = CLAMP( g, 0.0F, 1.0F );
  517.                   b = CLAMP( b, 0.0F, 1.0F );
  518.                   a = CLAMP( a, 0.0F, 1.0F );
  519.                }
  520.                /* Apply pixel maps */
  521.                if (ctx->Pixel.MapColorFlag) {
  522.                   GLint ir = (GLint) (r*ctx->Pixel.MapRtoRsize);
  523.                   GLint ig = (GLint) (g*ctx->Pixel.MapGtoGsize);
  524.                   GLint ib = (GLint) (b*ctx->Pixel.MapBtoBsize);
  525.                   GLint ia = (GLint) (a*ctx->Pixel.MapAtoAsize);
  526.                   r = ctx->Pixel.MapRtoR[ir];
  527.                   g = ctx->Pixel.MapGtoG[ig];
  528.                   b = ctx->Pixel.MapBtoB[ib];
  529.                   a = ctx->Pixel.MapAtoA[ia];
  530.                }
  531.                red   = (GLint) (r * 255.0F);
  532.                green = (GLint) (g * 255.0F);
  533.                blue  = (GLint) (b * 255.0F);
  534.                alpha = (GLint) (a * 255.0F);
  535.             }
  536.  
  537.             /* store texel (components are GLubytes in [0,255]) */
  538.             switch (texImage->Format) {
  539.                case GL_COLOR_INDEX:
  540.                   texImage->Data[pixel] = red; /* really an index */
  541.                   break;
  542.                case GL_ALPHA:
  543.                   texImage->Data[pixel] = alpha;
  544.                   break;
  545.                case GL_LUMINANCE:
  546.                   texImage->Data[pixel] = red;
  547.                   break;
  548.                case GL_LUMINANCE_ALPHA:
  549.                   texImage->Data[pixel*2+0] = red;
  550.                   texImage->Data[pixel*2+1] = alpha;
  551.                   break;
  552.                case GL_INTENSITY:
  553.                   texImage->Data[pixel] = red;
  554.                   break;
  555.                case GL_RGB:
  556.                   texImage->Data[pixel*3+0] = red;
  557.                   texImage->Data[pixel*3+1] = green;
  558.                   texImage->Data[pixel*3+2] = blue;
  559.                   break;
  560.                case GL_RGBA:
  561.                   texImage->Data[pixel*4+0] = red;
  562.                   texImage->Data[pixel*4+1] = green;
  563.                   texImage->Data[pixel*4+2] = blue;
  564.                   texImage->Data[pixel*4+3] = alpha;
  565.                   break;
  566.                default:
  567.                   gl_problem(ctx,"Bad format (3) in image_to_texture");
  568.                   return NULL;
  569.             }
  570.          }
  571.          break;
  572.  
  573.       case GL_FLOAT:
  574.          for (pixel=0; pixel<numPixels; pixel++) {
  575.             GLfloat red, green, blue, alpha;
  576.             switch (texImage->Format) {
  577.                case GL_COLOR_INDEX:
  578.                   if (decode_internal_format(internalFormat)==GL_COLOR_INDEX) {
  579.                      /* a paletted texture */
  580.                      GLint index = (GLint) ((GLfloat*) image->Data)[pixel];
  581.                      red = index;
  582.                   }
  583.                   else {
  584.                      GLint shift = ctx->Pixel.IndexShift;
  585.                      GLint offset = ctx->Pixel.IndexOffset;
  586.                      /* MapIto[RGBA]Size must be powers of two */
  587.                      GLint rMask = ctx->Pixel.MapItoRsize-1;
  588.                      GLint gMask = ctx->Pixel.MapItoGsize-1;
  589.                      GLint bMask = ctx->Pixel.MapItoBsize-1;
  590.                      GLint aMask = ctx->Pixel.MapItoAsize-1;
  591.                      /* Fetch image color index */
  592.                      GLint index = (GLint) ((GLfloat*) image->Data)[pixel];
  593.                      /* apply index shift and offset */
  594.                      if (shift>=0) {
  595.                         index = (index << shift) + offset;
  596.                      }
  597.                      else {
  598.                         index = (index >> -shift) + offset;
  599.                      }
  600.                      /* convert index to RGBA */
  601.                      red   = ctx->Pixel.MapItoR[index & rMask];
  602.                      green = ctx->Pixel.MapItoG[index & gMask];
  603.                      blue  = ctx->Pixel.MapItoB[index & bMask];
  604.                      alpha = ctx->Pixel.MapItoA[index & aMask];
  605.                   }
  606.                   break;
  607.                case GL_RGB:
  608.                   /* Fetch image RGBA values */
  609.                   red   = ((GLfloat*) image->Data)[pixel*3+0];
  610.                   green = ((GLfloat*) image->Data)[pixel*3+1];
  611.                   blue  = ((GLfloat*) image->Data)[pixel*3+2];
  612.                   alpha = 1.0;
  613.                   break;
  614.                case GL_RGBA:
  615.                   red   = ((GLfloat*) image->Data)[pixel*4+0];
  616.                   green = ((GLfloat*) image->Data)[pixel*4+1];
  617.                   blue  = ((GLfloat*) image->Data)[pixel*4+2];
  618.                   alpha = ((GLfloat*) image->Data)[pixel*4+3];
  619.                   break;
  620.                case GL_RED:
  621.                   red   = ((GLfloat*) image->Data)[pixel];
  622.                   green = 0.0;
  623.                   blue  = 0.0;
  624.                   alpha = 1.0;
  625.                   break;
  626.                case GL_GREEN:
  627.                   red   = 0.0;
  628.                   green = ((GLfloat*) image->Data)[pixel];
  629.                   blue  = 0.0;
  630.                   alpha = 1.0;
  631.                   break;
  632.                case GL_BLUE:
  633.                   red   = 0.0;
  634.                   green = 0.0;
  635.                   blue  = ((GLfloat*) image->Data)[pixel];
  636.                   alpha = 1.0;
  637.                   break;
  638.                case GL_ALPHA:
  639.                   red   = 0.0;
  640.                   green = 0.0;
  641.                   blue  = 0.0;
  642.                   alpha = ((GLfloat*) image->Data)[pixel];
  643.                   break;
  644.                case GL_LUMINANCE: 
  645.                   red   = ((GLfloat*) image->Data)[pixel];
  646.                   green = red;
  647.                   blue  = red;
  648.                   alpha = 1.0;
  649.                   break;
  650.               case GL_LUMINANCE_ALPHA:
  651.                   red   = ((GLfloat*) image->Data)[pixel*2+0];
  652.                   green = red;
  653.                   blue  = red;
  654.                   alpha = ((GLfloat*) image->Data)[pixel*2+1];
  655.                   break;
  656.                default:
  657.                   gl_problem(ctx,"Bad format (4) in image_to_texture");
  658.                   return NULL;
  659.             }
  660.             
  661.             if (image->Format!=GL_COLOR_INDEX) {
  662.                /* Apply RGBA scale and bias */
  663.                if (scaleOrBias) {
  664.                   red   = red   * ctx->Pixel.RedScale   + ctx->Pixel.RedBias;
  665.                   green = green * ctx->Pixel.GreenScale + ctx->Pixel.GreenBias;
  666.                   blue  = blue  * ctx->Pixel.BlueScale  + ctx->Pixel.BlueBias;
  667.                   alpha = alpha * ctx->Pixel.AlphaScale + ctx->Pixel.AlphaBias;
  668.                   red   = CLAMP( red,    0.0F, 1.0F );
  669.                   green = CLAMP( green,  0.0F, 1.0F );
  670.                   blue  = CLAMP( blue,   0.0F, 1.0F );
  671.                   alpha = CLAMP( alpha,  0.0F, 1.0F );
  672.                }
  673.                /* Apply pixel maps */
  674.                if (ctx->Pixel.MapColorFlag) {
  675.                   GLint ir = (GLint) (red  *ctx->Pixel.MapRtoRsize);
  676.                   GLint ig = (GLint) (green*ctx->Pixel.MapGtoGsize);
  677.                   GLint ib = (GLint) (blue *ctx->Pixel.MapBtoBsize);
  678.                   GLint ia = (GLint) (alpha*ctx->Pixel.MapAtoAsize);
  679.                   red   = ctx->Pixel.MapRtoR[ir];
  680.                   green = ctx->Pixel.MapGtoG[ig];
  681.                   blue  = ctx->Pixel.MapBtoB[ib];
  682.                   alpha = ctx->Pixel.MapAtoA[ia];
  683.                }
  684.             }
  685.  
  686.             /* store texel (components are GLubytes in [0,255]) */
  687.             switch (texImage->Format) {
  688.                case GL_COLOR_INDEX:
  689.                   /* a paletted texture */
  690.                   texImage->Data[pixel] = (GLint) (red * 255.0F);
  691.                   break;
  692.                case GL_ALPHA:
  693.                   texImage->Data[pixel] = (GLint) (alpha * 255.0F);
  694.                   break;
  695.                case GL_LUMINANCE:
  696.                   texImage->Data[pixel] = (GLint) (red * 255.0F);
  697.                   break;
  698.                case GL_LUMINANCE_ALPHA:
  699.                   texImage->Data[pixel*2+0] = (GLint) (red * 255.0F);
  700.                   texImage->Data[pixel*2+1] = (GLint) (alpha * 255.0F);
  701.                   break;
  702.                case GL_INTENSITY:
  703.                   texImage->Data[pixel] = (GLint) (red * 255.0F);
  704.                   break;
  705.                case GL_RGB:
  706.                   texImage->Data[pixel*3+0] = (GLint) (red   * 255.0F);
  707.                   texImage->Data[pixel*3+1] = (GLint) (green * 255.0F);
  708.                   texImage->Data[pixel*3+2] = (GLint) (blue  * 255.0F);
  709.                   break;
  710.                case GL_RGBA:
  711.                   texImage->Data[pixel*4+0] = (GLint) (red   * 255.0F);
  712.                   texImage->Data[pixel*4+1] = (GLint) (green * 255.0F);
  713.                   texImage->Data[pixel*4+2] = (GLint) (blue  * 255.0F);
  714.                   texImage->Data[pixel*4+3] = (GLint) (alpha * 255.0F);
  715.                   break;
  716.                default:
  717.                   gl_problem(ctx,"Bad format (5) in image_to_texture");
  718.                   return NULL;
  719.             }
  720.          }
  721.          break;
  722.  
  723.       default:
  724.          gl_problem(ctx, "Bad image type in image_to_texture");
  725.          return NULL;
  726.    }
  727.  
  728.    return texImage;
  729. }
  730.  
  731.  
  732.  
  733. /*
  734.  * glTexImage[123]D can accept a NULL image pointer.  In this case we
  735.  * create a texture image with unspecified image contents per the OpenGL
  736.  * spec.
  737.  */
  738. static struct gl_texture_image *
  739. make_null_texture( GLcontext *ctx, GLenum internalFormat,
  740.                    GLsizei width, GLsizei height, GLsizei depth, GLint border )
  741. {
  742.    GLint components;
  743.    struct gl_texture_image *texImage;
  744.    GLint numPixels;
  745.    (void) ctx;
  746.  
  747.    /*internalFormat = decode_internal_format(internalFormat);*/
  748.    components = components_in_intformat(internalFormat);
  749.    numPixels = width * height * depth;
  750.  
  751.    texImage = gl_alloc_texture_image();
  752.    if (!texImage)
  753.       return NULL;
  754.  
  755.    texImage->Format = (GLenum) decode_internal_format(internalFormat);
  756.    texImage->IntFormat = internalFormat;
  757.    texImage->Border = border;
  758.    texImage->Width = width;
  759.    texImage->Height = height;
  760.    texImage->Depth = depth;
  761.    texImage->WidthLog2 = logbase2(width - 2*border);
  762.    if (height==1)  /* 1-D texture */
  763.       texImage->HeightLog2 = 0;
  764.    else
  765.       texImage->HeightLog2 = logbase2(height - 2*border);
  766.    if (depth==1)   /* 2-D texture */
  767.       texImage->DepthLog2 = 0;
  768.    else
  769.       texImage->DepthLog2 = logbase2(depth - 2*border);
  770.    texImage->Width2 = 1 << texImage->WidthLog2;
  771.    texImage->Height2 = 1 << texImage->HeightLog2;
  772.    texImage->Depth2 = 1 << texImage->DepthLog2;
  773.    texImage->MaxLog2 = MAX2( texImage->WidthLog2, texImage->HeightLog2 );
  774.  
  775.    /* XXX should we really allocate memory for the image or let it be NULL? */
  776.    /*texImage->Data = NULL;*/
  777.  
  778.    texImage->Data = (GLubyte *) malloc( numPixels * components );
  779.  
  780.    /*
  781.     * Let's see if anyone finds this.  If glTexImage2D() is called with
  782.     * a NULL image pointer then load the texture image with something
  783.     * interesting instead of leaving it indeterminate.
  784.     */
  785.    if (texImage->Data) {
  786.       char message[8][32] = {
  787.          "   X   X  XXXXX   XXX     X    ",
  788.          "   XX XX  X      X   X   X X   ",
  789.          "   X X X  X      X      X   X  ",
  790.          "   X   X  XXXX    XXX   XXXXX  ",
  791.          "   X   X  X          X  X   X  ",
  792.          "   X   X  X      X   X  X   X  ",
  793.          "   X   X  XXXXX   XXX   X   X  ",
  794.          "                               "
  795.       };
  796.  
  797.       GLubyte *imgPtr = texImage->Data;
  798.       GLint i, j, k;
  799.       for (i=0;i<height;i++) {
  800.          GLint srcRow = 7 - i % 8;
  801.          for (j=0;j<width;j++) {
  802.             GLint srcCol = j % 32;
  803.             GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70;
  804.             for (k=0;k<components;k++) {
  805.                *imgPtr++ = texel;
  806.             }
  807.          }
  808.       }
  809.    }
  810.  
  811.    return texImage;
  812. }
  813.  
  814.  
  815.  
  816.  
  817. /*
  818.  * Test glTexImagee1D() parameters for errors.
  819.  * Return:  GL_TRUE = an error was detected, GL_FALSE = no errors
  820.  */
  821. static GLboolean texture_1d_error_check( GLcontext *ctx, GLenum target,
  822.                                          GLint level, GLint internalFormat,
  823.                                          GLenum format, GLenum type,
  824.                                          GLint width, GLint border )
  825. {
  826.    GLint iformat;
  827.    if (target!=GL_TEXTURE_1D && target!=GL_PROXY_TEXTURE_1D) {
  828.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D" );
  829.       return GL_TRUE;
  830.    }
  831.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  832.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage1D(level)" );
  833.       return GL_TRUE;
  834.    }
  835.    iformat = decode_internal_format( internalFormat );
  836.    if (iformat<0) {
  837.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage1D(internalFormat)" );
  838.       return GL_TRUE;
  839.    }
  840.    if (border!=0 && border!=1) {
  841.       if (target!=GL_PROXY_TEXTURE_1D) {
  842.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage1D(border)" );
  843.       }
  844.       return GL_TRUE;
  845.    }
  846.    if (width<2*border || width>2+MAX_TEXTURE_SIZE) {
  847.       if (target!=GL_PROXY_TEXTURE_1D) {
  848.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage1D(width)" );
  849.       }
  850.       return GL_TRUE;
  851.    }
  852.    if (logbase2( width-2*border )<0) {
  853.       gl_error( ctx, GL_INVALID_VALUE,
  854.                "glTexImage1D(width != 2^k + 2*border)");
  855.       return GL_TRUE;
  856.    }
  857.    switch (format) {
  858.       case GL_COLOR_INDEX:
  859.       case GL_RED:
  860.       case GL_GREEN:
  861.       case GL_BLUE:
  862.       case GL_ALPHA:
  863.       case GL_RGB:
  864.       case GL_RGBA:
  865.       case GL_LUMINANCE:
  866.       case GL_LUMINANCE_ALPHA:
  867.       case GL_ABGR_EXT:
  868.          /* OK */
  869.          break;
  870.       default:
  871.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D(format)" );
  872.          return GL_TRUE;
  873.    }
  874.    switch (type) {
  875.       case GL_UNSIGNED_BYTE:
  876.       case GL_BYTE:
  877.       case GL_UNSIGNED_SHORT:
  878.       case GL_SHORT:
  879.       case GL_UNSIGNED_INT:
  880.       case GL_INT:
  881.       case GL_FLOAT:
  882.          /* OK */
  883.          break;
  884.       default:
  885.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D(type)" );
  886.          return GL_TRUE;
  887.    }
  888.    return GL_FALSE;
  889. }
  890.  
  891.  
  892. /*
  893.  * Test glTexImagee2D() parameters for errors.
  894.  * Return:  GL_TRUE = an error was detected, GL_FALSE = no errors
  895.  */
  896. static GLboolean texture_2d_error_check( GLcontext *ctx, GLenum target,
  897.                                          GLint level, GLint internalFormat,
  898.                                          GLenum format, GLenum type,
  899.                                          GLint width, GLint height,
  900.                                          GLint border )
  901. {
  902.    GLint iformat;
  903.    if (target!=GL_TEXTURE_2D && target!=GL_PROXY_TEXTURE_2D) {
  904.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" );
  905.       return GL_TRUE;
  906.    }
  907.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  908.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(level)" );
  909.       return GL_TRUE;
  910.    }
  911.    iformat = decode_internal_format( internalFormat );
  912.    if (iformat<0) {
  913.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(internalFormat)" );
  914.       return GL_TRUE;
  915.    }
  916.    if (border!=0 && border!=1) {
  917.       if (target!=GL_PROXY_TEXTURE_2D) {
  918.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(border)" );
  919.       }
  920.       return GL_TRUE;
  921.    }
  922.    if (width<2*border || width>2+MAX_TEXTURE_SIZE) {
  923.       if (target!=GL_PROXY_TEXTURE_2D) {
  924.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(width)" );
  925.       }
  926.       return GL_TRUE;
  927.    }
  928.    if (height<2*border || height>2+MAX_TEXTURE_SIZE) {
  929.       if (target!=GL_PROXY_TEXTURE_2D) {
  930.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(height)" );
  931.       }
  932.       return GL_TRUE;
  933.    }
  934.    if (logbase2( width-2*border )<0) {
  935.       gl_error( ctx,GL_INVALID_VALUE,
  936.                "glTexImage2D(width != 2^k + 2*border)");
  937.       return GL_TRUE;
  938.    }
  939.    if (logbase2( height-2*border )<0) {
  940.       gl_error( ctx,GL_INVALID_VALUE,
  941.                "glTexImage2D(height != 2^k + 2*border)");
  942.       return GL_TRUE;
  943.    }
  944.    switch (format) {
  945.       case GL_COLOR_INDEX:
  946.       case GL_RED:
  947.       case GL_GREEN:
  948.       case GL_BLUE:
  949.       case GL_ALPHA:
  950.       case GL_RGB:
  951.       case GL_RGBA:
  952.       case GL_LUMINANCE:
  953.       case GL_LUMINANCE_ALPHA:
  954.       case GL_ABGR_EXT:
  955.          /* OK */
  956.          break;
  957.       default:
  958.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(format)" );
  959.          return GL_TRUE;
  960.    }
  961.    switch (type) {
  962.       case GL_UNSIGNED_BYTE:
  963.       case GL_BYTE:
  964.       case GL_UNSIGNED_SHORT:
  965.       case GL_SHORT:
  966.       case GL_UNSIGNED_INT:
  967.       case GL_INT:
  968.       case GL_FLOAT:
  969.          /* OK */
  970.          break;
  971.       default:
  972.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(type)" );
  973.          return GL_TRUE;
  974.    }
  975.    return GL_FALSE;
  976. }
  977.  
  978.  
  979. /*
  980.  * Test glTexImage3DEXT() parameters for errors.
  981.  * Return:  GL_TRUE = an error was detected, GL_FALSE = no errors
  982.  */
  983. static GLboolean texture_3d_error_check( GLcontext *ctx, GLenum target,
  984.                                          GLint level, GLint internalFormat,
  985.                                          GLenum format, GLenum type,
  986.                                          GLint width, GLint height,
  987.                                          GLint depth, GLint border )
  988. {
  989.    GLint iformat;
  990.    if (target!=GL_TEXTURE_3D_EXT && target!=GL_PROXY_TEXTURE_3D_EXT) {
  991.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage3DEXT(target)" );
  992.       return GL_TRUE;
  993.    }
  994.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  995.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(level)" );
  996.       return GL_TRUE;
  997.    }
  998.    iformat = decode_internal_format( internalFormat );
  999.    if (iformat<0) {
  1000.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(internalFormat)" );
  1001.       return GL_TRUE;
  1002.    }
  1003.    if (border!=0 && border!=1) {
  1004.       if (target!=GL_PROXY_TEXTURE_3D_EXT) {
  1005.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(border)" );
  1006.       }
  1007.       return GL_TRUE;
  1008.    }
  1009.    if (width<2*border || width>2+MAX_TEXTURE_SIZE) {
  1010.       if (target!=GL_PROXY_TEXTURE_3D_EXT) {
  1011.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(width)" );
  1012.       }
  1013.       return GL_TRUE;
  1014.    }
  1015.    if (height<2*border || height>2+MAX_TEXTURE_SIZE) {
  1016.       if (target!=GL_PROXY_TEXTURE_3D_EXT) {
  1017.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(height)" );
  1018.       }
  1019.       return GL_TRUE;
  1020.    }
  1021.    if (depth<2*border || depth>2+MAX_TEXTURE_SIZE) {
  1022.       if (target!=GL_PROXY_TEXTURE_3D_EXT) {
  1023.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(depth)" );
  1024.       }
  1025.       return GL_TRUE;
  1026.    }
  1027.    if (logbase2( width-2*border )<0) {
  1028.       gl_error( ctx,GL_INVALID_VALUE,
  1029.                "glTexImage3DEXT(width != 2^k + 2*border))");
  1030.       return GL_TRUE;
  1031.    }
  1032.    if (logbase2( height-2*border )<0) {
  1033.       gl_error( ctx,GL_INVALID_VALUE,
  1034.                "glTexImage3DEXT(height != 2^k + 2*border))");
  1035.       return GL_TRUE;
  1036.    }
  1037.    if (logbase2( depth-2*border )<0) {
  1038.       gl_error( ctx,GL_INVALID_VALUE,
  1039.                "glTexImage3DEXT(depth  != 2^k + 2*border))");
  1040.       return GL_TRUE;
  1041.    }
  1042.    switch (format) {
  1043.       case GL_COLOR_INDEX:
  1044.       case GL_RED:
  1045.       case GL_GREEN:
  1046.       case GL_BLUE:
  1047.       case GL_ALPHA:
  1048.       case GL_RGB:
  1049.       case GL_RGBA:
  1050.       case GL_LUMINANCE:
  1051.       case GL_LUMINANCE_ALPHA:
  1052.       case GL_ABGR_EXT:
  1053.          /* OK */
  1054.          break;
  1055.       default:
  1056.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage3DEXT(format)" );
  1057.          return GL_TRUE;
  1058.    }
  1059.    switch (type) {
  1060.       case GL_UNSIGNED_BYTE:
  1061.       case GL_BYTE:
  1062.       case GL_UNSIGNED_SHORT:
  1063.       case GL_SHORT:
  1064.       case GL_UNSIGNED_INT:
  1065.       case GL_INT:
  1066.       case GL_FLOAT:
  1067.          /* OK */
  1068.          break;
  1069.       default:
  1070.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage3DEXT(type)" );
  1071.          return GL_TRUE;
  1072.    }
  1073.    return GL_FALSE;
  1074. }
  1075.  
  1076.  
  1077.  
  1078. /*
  1079.  * Called from the API.  Note that width includes the border.
  1080.  */
  1081. void gl_TexImage1D( GLcontext *ctx,
  1082.                     GLenum target, GLint level, GLint internalformat,
  1083.             GLsizei width, GLint border, GLenum format,
  1084.             GLenum type, struct gl_image *image )
  1085. {
  1086.    struct gl_texture_set *texSet = &ctx->Texture.Set[ctx->Texture.CurrentSet];
  1087.    if (INSIDE_BEGIN_END(ctx)) {
  1088.       gl_error( ctx, GL_INVALID_OPERATION, "glTexImage1D" );
  1089.       return;
  1090.    }
  1091.  
  1092.    if (target==GL_TEXTURE_1D) {
  1093.       struct gl_texture_image *teximage;
  1094.       if (texture_1d_error_check( ctx, target, level, internalformat,
  1095.                                   format, type, width, border )) {
  1096.          /* error in texture image was detected */
  1097.          return;
  1098.       }
  1099.  
  1100.       /* free current texture image, if any */
  1101.       if (texSet->Current1D->Image[level]) {
  1102.          gl_free_texture_image( texSet->Current1D->Image[level] );
  1103.       }
  1104.  
  1105.       /* make new texture from source image */
  1106.       if (image) {
  1107.          teximage = image_to_texture(ctx, image, internalformat, border);
  1108.       }
  1109.       else {
  1110.          teximage = make_null_texture(ctx, (GLenum) internalformat,
  1111.                                       width, 1, 1, border);
  1112.       }
  1113.  
  1114.       /* install new texture image */
  1115.       texSet->Current1D->Image[level] = teximage;
  1116.       texSet->Current1D->Dirty = GL_TRUE;
  1117.       ctx->Texture.AnyDirty = GL_TRUE;
  1118.       ctx->NewState |= NEW_TEXTURING;
  1119.  
  1120.       /* free the source image */
  1121.       if (image && image->RefCount==0) {
  1122.          /* if RefCount>0 then image must be in a display list */
  1123.          gl_free_image(image);
  1124.       }
  1125.  
  1126.       /* tell driver about change */
  1127.       if (ctx->Driver.TexImage) {
  1128.          (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D,
  1129.                                   texSet->Current1D,
  1130.                                   level, internalformat, teximage );
  1131.       }
  1132.    }
  1133.    else if (target==GL_PROXY_TEXTURE_1D) {
  1134.       /* Proxy texture: check for errors and update proxy state */
  1135.       if (texture_1d_error_check( ctx, target, level, internalformat,
  1136.                                   format, type, width, border )) {
  1137.          if (level>=0 && level<MAX_TEXTURE_LEVELS) {
  1138.             MEMSET( ctx->Texture.Proxy1D->Image[level], 0,
  1139.                     sizeof(struct gl_texture_image) );
  1140.          }
  1141.       }
  1142.       else {
  1143.          ctx->Texture.Proxy1D->Image[level]->Format = (GLenum) internalformat;
  1144.          ctx->Texture.Proxy1D->Image[level]->IntFormat = internalformat;
  1145.          ctx->Texture.Proxy1D->Image[level]->Border = border;
  1146.          ctx->Texture.Proxy1D->Image[level]->Width = width;
  1147.          ctx->Texture.Proxy1D->Image[level]->Height = 1;
  1148.       }
  1149.       if (image && image->RefCount==0) {
  1150.          /* if RefCount>0 then image must be in a display list */
  1151.          gl_free_image(image);
  1152.       }
  1153.    }
  1154.    else {
  1155.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
  1156.       return;
  1157.    }
  1158. }
  1159.  
  1160.  
  1161.  
  1162.  
  1163. /*
  1164.  * Called by the API or display list executor.
  1165.  * Note that width and height include the border.
  1166.  */
  1167. void gl_TexImage2D( GLcontext *ctx,
  1168.                     GLenum target, GLint level, GLint internalformat,
  1169.                     GLsizei width, GLsizei height, GLint border,
  1170.                     GLenum format, GLenum type,
  1171.                     struct gl_image *image )
  1172. {
  1173.    struct gl_texture_set *texSet = &ctx->Texture.Set[ctx->Texture.CurrentSet];
  1174.    if (INSIDE_BEGIN_END(ctx)) {
  1175.       gl_error( ctx, GL_INVALID_OPERATION, "glTexImage2D" );
  1176.       return;
  1177.    }
  1178.  
  1179.    if (target==GL_TEXTURE_2D) {
  1180.       struct gl_texture_image *teximage;
  1181.       if (texture_2d_error_check( ctx, target, level, internalformat,
  1182.                                   format, type, width, height, border )) {
  1183.          /* error in texture image was detected */
  1184.          return;
  1185.       }
  1186.  
  1187.       /* free current texture image, if any */
  1188.       if (texSet->Current2D->Image[level]) {
  1189.          gl_free_texture_image( texSet->Current2D->Image[level] );
  1190.       }
  1191.  
  1192.       /* make new texture from source image */
  1193.       if (image) {
  1194.          teximage = image_to_texture(ctx, image, internalformat, border);
  1195.       }
  1196.       else {
  1197.          teximage = make_null_texture(ctx, (GLenum) internalformat,
  1198.                                       width, height, 1, border);
  1199.       }
  1200.  
  1201.       /* install new texture image */
  1202.       texSet->Current2D->Image[level] = teximage;
  1203.       texSet->Current2D->Dirty = GL_TRUE;
  1204.       ctx->Texture.AnyDirty = GL_TRUE;
  1205.       ctx->NewState |= NEW_TEXTURING;
  1206.  
  1207.       /* free the source image */
  1208.       if (image && image->RefCount==0) {
  1209.          /* if RefCount>0 then image must be in a display list */
  1210.          gl_free_image(image);
  1211.       }
  1212.  
  1213.       /* tell driver about change */
  1214.       if (ctx->Driver.TexImage) {
  1215.          (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D,
  1216.                                   texSet->Current2D,
  1217.                                   level, internalformat, teximage );
  1218.       }
  1219.    }
  1220.    else if (target==GL_PROXY_TEXTURE_2D) {
  1221.       /* Proxy texture: check for errors and update proxy state */
  1222.       if (texture_2d_error_check( ctx, target, level, internalformat,
  1223.                                   format, type, width, height, border )) {
  1224.          if (level>=0 && level<MAX_TEXTURE_LEVELS) {
  1225.             MEMSET( ctx->Texture.Proxy2D->Image[level], 0,
  1226.                     sizeof(struct gl_texture_image) );
  1227.          }
  1228.       }
  1229.       else {
  1230.          ctx->Texture.Proxy2D->Image[level]->Format = (GLenum) internalformat;
  1231.          ctx->Texture.Proxy2D->Image[level]->IntFormat = internalformat;
  1232.          ctx->Texture.Proxy2D->Image[level]->Border = border;
  1233.          ctx->Texture.Proxy2D->Image[level]->Width = width;
  1234.          ctx->Texture.Proxy2D->Image[level]->Height = height;
  1235.       }
  1236.       if (image && image->RefCount==0) {
  1237.          /* if RefCount>0 then image must be in a display list */
  1238.          gl_free_image(image);
  1239.       }
  1240.    }
  1241.    else {
  1242.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" );
  1243.       return;
  1244.    }
  1245. }
  1246.  
  1247.  
  1248.  
  1249. /*
  1250.  * Called by the API or display list executor.
  1251.  * Note that width and height include the border.
  1252.  */
  1253. void gl_TexImage3DEXT( GLcontext *ctx,
  1254.                        GLenum target, GLint level, GLint internalformat,
  1255.                        GLsizei width, GLsizei height, GLsizei depth,
  1256.                        GLint border, GLenum format, GLenum type,
  1257.                        struct gl_image *image )
  1258. {
  1259.    struct gl_texture_set *texSet = &ctx->Texture.Set[ctx->Texture.CurrentSet];
  1260.    if (INSIDE_BEGIN_END(ctx)) {
  1261.       gl_error( ctx, GL_INVALID_OPERATION, "glTexImage3DEXT" );
  1262.       return;
  1263.    }
  1264.  
  1265.    if (target==GL_TEXTURE_3D_EXT) {
  1266.       struct gl_texture_image *teximage;
  1267.       if (texture_3d_error_check( ctx, target, level, internalformat,
  1268.                                   format, type, width, height, depth,
  1269.                                   border )) {
  1270.          /* error in texture image was detected */
  1271.          return;
  1272.       }
  1273.  
  1274.       /* free current texture image, if any */
  1275.       if (texSet->Current3D->Image[level]) {
  1276.          gl_free_texture_image( texSet->Current3D->Image[level] );
  1277.       }
  1278.  
  1279.       /* make new texture from source image */
  1280.       if (image) {
  1281.          teximage = image_to_texture(ctx, image, internalformat, border);
  1282.       }
  1283.       else {
  1284.          teximage = make_null_texture(ctx, (GLenum) internalformat,
  1285.                                       width, height, depth, border);
  1286.       }
  1287.  
  1288.       /* install new texture image */
  1289.       texSet->Current3D->Image[level] = teximage;
  1290.       texSet->Current3D->Dirty = GL_TRUE;
  1291.       ctx->Texture.AnyDirty = GL_TRUE;
  1292.       ctx->NewState |= NEW_TEXTURING;
  1293.  
  1294.       /* free the source image */
  1295.       if (image && image->RefCount==0) {
  1296.          /* if RefCount>0 then image must be in a display list */
  1297.          gl_free_image(image);
  1298.       }
  1299.  
  1300.       /* tell driver about change */
  1301.       if (ctx->Driver.TexImage) {
  1302.          (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_3D_EXT,
  1303.                                   texSet->Current3D,
  1304.                                   level, internalformat, teximage );
  1305.       }
  1306.    }
  1307.    else if (target==GL_PROXY_TEXTURE_3D_EXT) {
  1308.       /* Proxy texture: check for errors and update proxy state */
  1309.       if (texture_3d_error_check( ctx, target, level, internalformat,
  1310.                                   format, type, width, height, depth,
  1311.                                   border )) {
  1312.          if (level>=0 && level<MAX_TEXTURE_LEVELS) {
  1313.             MEMSET( ctx->Texture.Proxy3D->Image[level], 0,
  1314.                     sizeof(struct gl_texture_image) );
  1315.          }
  1316.       }
  1317.       else {
  1318.          ctx->Texture.Proxy3D->Image[level]->Format = (GLenum) internalformat;
  1319.          ctx->Texture.Proxy3D->Image[level]->IntFormat = internalformat;
  1320.          ctx->Texture.Proxy3D->Image[level]->Border = border;
  1321.          ctx->Texture.Proxy3D->Image[level]->Width = width;
  1322.          ctx->Texture.Proxy3D->Image[level]->Height = height;
  1323.          ctx->Texture.Proxy3D->Image[level]->Depth  = depth;
  1324.       }
  1325.       if (image && image->RefCount==0) {
  1326.          /* if RefCount>0 then image must be in a display list */
  1327.          gl_free_image(image);
  1328.       }
  1329.    }
  1330.    else {
  1331.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage3DEXT(target)" );
  1332.       return;
  1333.    }
  1334. }
  1335.  
  1336.  
  1337.  
  1338. void gl_GetTexImage( GLcontext *ctx, GLenum target, GLint level, GLenum format,
  1339.                      GLenum type, GLvoid *pixels )
  1340. {
  1341.    const struct gl_texture_object *texObj;
  1342.  
  1343.    if (INSIDE_BEGIN_END(ctx)) {
  1344.       gl_error( ctx, GL_INVALID_OPERATION, "glGetTexImage" );
  1345.       return;
  1346.    }
  1347.  
  1348.    if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
  1349.       gl_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
  1350.       return;
  1351.    }
  1352.  
  1353.    if (gl_sizeof_type(type) <= 0) {
  1354.       gl_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
  1355.       return;
  1356.    }
  1357.  
  1358.    if (gl_components_in_format(format) <= 0) {
  1359.       gl_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
  1360.       return;
  1361.    }
  1362.  
  1363.    if (!pixels)
  1364.       return;  /* XXX generate an error??? */
  1365.  
  1366.    switch (target) {
  1367.       case GL_TEXTURE_1D:
  1368.          texObj = ctx->Texture.Set[ctx->Texture.CurrentSet].Current1D;
  1369.          break;
  1370.       case GL_TEXTURE_2D:
  1371.          texObj = ctx->Texture.Set[ctx->Texture.CurrentSet].Current2D;
  1372.          break;
  1373.       case GL_TEXTURE_3D:
  1374.          texObj = ctx->Texture.Set[ctx->Texture.CurrentSet].Current3D;
  1375.          break;
  1376.       default:
  1377.          gl_error( ctx, GL_INVALID_ENUM, "glGetTexImage(target)" );
  1378.          return;
  1379.    }
  1380.  
  1381.    if (texObj->Image[level] && texObj->Image[level]->Data) {
  1382.       const struct gl_texture_image *texImage = texObj->Image[level];
  1383.       GLint width = texImage->Width;
  1384.       GLint height = texImage->Height;
  1385.       GLint row;
  1386.  
  1387.       for (row = 0; row < height; row++) {
  1388.          /* compute destination address in client memory */
  1389.          GLvoid *dest = gl_pixel_addr_in_image( &ctx->Unpack, pixels,
  1390.                                                 width, height,
  1391.                                                 format, type, 0, row, 0);
  1392.  
  1393.          assert(dest);
  1394.          if (texImage->Format == GL_RGBA) {
  1395.             const GLubyte *src = texImage->Data + row * width * 4 * sizeof(GLubyte);
  1396.             gl_pack_rgba_span( ctx, width, (void *) src, format, type, dest );
  1397.          }
  1398.          else {
  1399.             /* fetch RGBA row from texture image then pack it in client mem */
  1400.             GLubyte rgba[MAX_WIDTH][4];
  1401.             GLint i;
  1402.             const GLubyte *src;
  1403.             switch (texImage->Format) {
  1404.                case GL_ALPHA:
  1405.                   src = texImage->Data + row * width * sizeof(GLubyte);
  1406.                   for (i = 0; i < width; i++) {
  1407.                      rgba[i][RCOMP] = 255;
  1408.                      rgba[i][GCOMP] = 255;
  1409.                      rgba[i][BCOMP] = 255;
  1410.                      rgba[i][ACOMP] = src[i];
  1411.                   }
  1412.                   break;
  1413.                case GL_LUMINANCE:
  1414.                   src = texImage->Data + row * width * sizeof(GLubyte);
  1415.                   for (i = 0; i < width; i++) {
  1416.                      rgba[i][RCOMP] = src[i];
  1417.                      rgba[i][GCOMP] = src[i];
  1418.                      rgba[i][BCOMP] = src[i];
  1419.                      rgba[i][ACOMP] = 255;
  1420.                    }
  1421.                   break;
  1422.                case GL_LUMINANCE_ALPHA:
  1423.                   src = texImage->Data + row * 2 * width * sizeof(GLubyte);
  1424.                   for (i = 0; i < width; i++) {
  1425.                      rgba[i][RCOMP] = src[i*2+0];
  1426.                      rgba[i][GCOMP] = src[i*2+0];
  1427.                      rgba[i][BCOMP] = src[i*2+0];
  1428.                      rgba[i][ACOMP] = src[i*2+1];
  1429.                   }
  1430.                   break;
  1431.                case GL_INTENSITY:
  1432.                   src = texImage->Data + row * width * sizeof(GLubyte);
  1433.                   for (i = 0; i < width; i++) {
  1434.                      rgba[i][RCOMP] = src[i];
  1435.                      rgba[i][GCOMP] = src[i];
  1436.                      rgba[i][BCOMP] = src[i];
  1437.                      rgba[i][ACOMP] = 255;
  1438.                   }
  1439.                   break;
  1440.                case GL_RGB:
  1441.                   src = texImage->Data + row * 3 * width * sizeof(GLubyte);
  1442.                   for (i = 0; i < width; i++) {
  1443.                      rgba[i][RCOMP] = src[i*3+0];
  1444.                      rgba[i][GCOMP] = src[i*3+1];
  1445.                      rgba[i][BCOMP] = src[i*3+2];
  1446.                      rgba[i][ACOMP] = 255;
  1447.                   }
  1448.                   break;
  1449.                case GL_RGBA:
  1450.                   /* this special case should have been handled above! */
  1451.                   gl_problem( ctx, "error 1 in gl_GetTexImage" );
  1452.                   break;
  1453.                case GL_COLOR_INDEX:
  1454.                   gl_problem( ctx, "GL_COLOR_INDEX not implemented in gl_GetTexImage" );
  1455.                   break;
  1456.                default:
  1457.                   gl_problem( ctx, "bad format in gl_GetTexImage" );
  1458.             }
  1459.             gl_pack_rgba_span( ctx, width, rgba, format, type, dest );
  1460.          }
  1461.       }
  1462.    }
  1463. }
  1464.  
  1465.  
  1466.  
  1467. /*
  1468.  * Unpack the image data given to glTexSubImage[12]D.
  1469.  * This function is just a wrapper for gl_unpack_image() but it does
  1470.  * some extra error checking.
  1471.  */
  1472. struct gl_image *
  1473. gl_unpack_texsubimage( GLcontext *ctx, GLint width, GLint height,
  1474.                        GLenum format, GLenum type, const GLvoid *pixels )
  1475. {
  1476.    if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
  1477.       return NULL;
  1478.    }
  1479.  
  1480.    if (format==GL_STENCIL_INDEX || format==GL_DEPTH_COMPONENT){
  1481.       return NULL;
  1482.    }
  1483.  
  1484.    if (gl_sizeof_type(type)<=0) {
  1485.       return NULL;
  1486.    }
  1487.  
  1488.    return gl_unpack_image3D( ctx, width, height, 1, format, type, pixels );
  1489. }
  1490.  
  1491.  
  1492. /*
  1493.  * Unpack the image data given to glTexSubImage3D.
  1494.  * This function is just a wrapper for gl_unpack_image() but it does
  1495.  * some extra error checking.
  1496.  */
  1497. struct gl_image *
  1498. gl_unpack_texsubimage3D( GLcontext *ctx, GLint width, GLint height, GLint depth,
  1499.                          GLenum format, GLenum type, const GLvoid *pixels )
  1500. {
  1501.    if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
  1502.       return NULL;
  1503.    }
  1504.  
  1505.    if (format==GL_STENCIL_INDEX || format==GL_DEPTH_COMPONENT){
  1506.       return NULL;
  1507.    }
  1508.  
  1509.    if (gl_sizeof_type(type)<=0) {
  1510.       return NULL;
  1511.    }
  1512.  
  1513.    return gl_unpack_image3D( ctx, width, height, depth, format, type, pixels );
  1514. }
  1515.  
  1516.  
  1517.  
  1518. void gl_TexSubImage1D( GLcontext *ctx,
  1519.                        GLenum target, GLint level, GLint xoffset,
  1520.                        GLsizei width, GLenum format, GLenum type,
  1521.                        struct gl_image *image )
  1522. {
  1523.    struct gl_texture_set *texSet = &ctx->Texture.Set[ctx->Texture.CurrentSet];
  1524.    struct gl_texture_image *destTex;
  1525.  
  1526.    if (target!=GL_TEXTURE_1D) {
  1527.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" );
  1528.       return;
  1529.    }
  1530.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  1531.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(level)" );
  1532.       return;
  1533.    }
  1534.  
  1535.    destTex = texSet->Current1D->Image[level];
  1536.    if (!destTex) {
  1537.       gl_error( ctx, GL_INVALID_OPERATION, "glTexSubImage1D" );
  1538.       return;
  1539.    }
  1540.  
  1541.    if (xoffset < -((GLint)destTex->Border)) {
  1542.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage1D(xoffset)" );
  1543.       return;
  1544.    }
  1545.    if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) {
  1546.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage1D(xoffset+width)" );
  1547.       return;
  1548.    }
  1549.  
  1550.    if (image) {
  1551.       /* unpacking must have been error-free */
  1552.       GLint texcomponents = components_in_intformat(destTex->Format);
  1553.  
  1554.       if (image->Type==GL_UNSIGNED_BYTE && texcomponents==image->Components) {
  1555.          /* Simple case, just byte copy image data into texture image */
  1556.          /* row by row. */
  1557.          GLubyte *dst = destTex->Data + texcomponents * xoffset;
  1558.          GLubyte *src = (GLubyte *) image->Data;
  1559.          MEMCPY( dst, src, width * texcomponents );
  1560.       }
  1561.       else {
  1562.          /* General case, convert image pixels into texels, scale, bias, etc */
  1563.          struct gl_texture_image *subTexImg = image_to_texture(ctx, image,
  1564.                                         destTex->IntFormat, destTex->Border);
  1565.          GLubyte *dst = destTex->Data + texcomponents * xoffset;
  1566.          GLubyte *src = subTexImg->Data;
  1567.          MEMCPY( dst, src, width * texcomponents );
  1568.          gl_free_texture_image(subTexImg);
  1569.       }
  1570.  
  1571.       /* if the image's reference count is zero, delete it now */
  1572.       if (image->RefCount==0) {
  1573.          gl_free_image(image);
  1574.       }
  1575.  
  1576.       texSet->Current1D->Dirty = GL_TRUE;
  1577.       ctx->Texture.AnyDirty = GL_TRUE;
  1578.  
  1579.       /* tell driver about change */
  1580.       if (ctx->Driver.TexSubImage) {
  1581.     (*ctx->Driver.TexSubImage)( ctx, GL_TEXTURE_1D,
  1582.                     texSet->Current1D, level,
  1583.                     xoffset,0,width,1,
  1584.                     texSet->Current1D->Image[level]->IntFormat,
  1585.                     destTex );
  1586.       }
  1587.       else {
  1588.     if (ctx->Driver.TexImage) {
  1589.       (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D, texSet->Current1D, level,
  1590.                    texSet->Current1D->Image[level]->IntFormat,
  1591.                    destTex );
  1592.     }
  1593.       }
  1594.    }
  1595.    else {
  1596.       /* if no image, an error must have occured, do more testing now */
  1597.       GLint components, size;
  1598.  
  1599.       if (width<0) {
  1600.          gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage1D(width)" );
  1601.          return;
  1602.       }
  1603.       if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
  1604.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(format)" );
  1605.          return;
  1606.       }
  1607.       components = components_in_intformat( format );
  1608.       if (components<0 || format==GL_STENCIL_INDEX
  1609.           || format==GL_DEPTH_COMPONENT){
  1610.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(format)" );
  1611.          return;
  1612.       }
  1613.       size = gl_sizeof_type( type );
  1614.       if (size<=0) {
  1615.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(type)" );
  1616.          return;
  1617.       }
  1618.       /* if we get here, probably ran out of memory during unpacking */
  1619.       gl_error( ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D" );
  1620.    }
  1621. }
  1622.  
  1623.  
  1624.  
  1625. void gl_TexSubImage2D( GLcontext *ctx,
  1626.                        GLenum target, GLint level,
  1627.                        GLint xoffset, GLint yoffset,
  1628.                        GLsizei width, GLsizei height,
  1629.                        GLenum format, GLenum type,
  1630.                        struct gl_image *image )
  1631. {
  1632.    struct gl_texture_set *texSet = &ctx->Texture.Set[ctx->Texture.CurrentSet];
  1633.    struct gl_texture_image *destTex;
  1634.  
  1635.    if (target!=GL_TEXTURE_2D) {
  1636.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
  1637.       return;
  1638.    }
  1639.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  1640.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(level)" );
  1641.       return;
  1642.    }
  1643.  
  1644.    destTex = texSet->Current2D->Image[level];
  1645.    if (!destTex) {
  1646.       gl_error( ctx, GL_INVALID_OPERATION, "glTexSubImage2D" );
  1647.       return;
  1648.    }
  1649.  
  1650.    if (xoffset < -((GLint)destTex->Border)) {
  1651.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(xoffset)" );
  1652.       return;
  1653.    }
  1654.    if (yoffset < -((GLint)destTex->Border)) {
  1655.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(yoffset)" );
  1656.       return;
  1657.    }
  1658.    if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) {
  1659.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(xoffset+width)" );
  1660.       return;
  1661.    }
  1662.    if (yoffset + height > (GLint) (destTex->Height + destTex->Border)) {
  1663.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(yoffset+height)" );
  1664.       return;
  1665.    }
  1666.  
  1667.    if (image) {
  1668.       /* unpacking must have been error-free */
  1669.       GLint texcomponents = components_in_intformat(destTex->Format);
  1670.  
  1671.       if (image->Type==GL_UNSIGNED_BYTE && texcomponents==image->Components) {
  1672.          /* Simple case, just byte copy image data into texture image */
  1673.          /* row by row. */
  1674.          GLubyte *dst = destTex->Data 
  1675.                       + (yoffset * destTex->Width + xoffset) * texcomponents;
  1676.          GLubyte *src = (GLubyte *) image->Data;
  1677.          GLint  j;
  1678.          for (j=0;j<height;j++) {
  1679.             MEMCPY( dst, src, width * texcomponents );
  1680.             dst += destTex->Width * texcomponents * sizeof(GLubyte);
  1681.             src += width * texcomponents * sizeof(GLubyte);
  1682.          }
  1683.       }
  1684.       else {
  1685.          /* General case, convert image pixels into texels, scale, bias, etc */
  1686.          struct gl_texture_image *subTexImg = image_to_texture(ctx, image,
  1687.                                         destTex->IntFormat, destTex->Border);
  1688.          GLubyte *dst = destTex->Data
  1689.                   + (yoffset * destTex->Width + xoffset) * texcomponents;
  1690.          GLubyte *src = subTexImg->Data;
  1691.          GLint j;
  1692.          for (j=0;j<height;j++) {
  1693.             MEMCPY( dst, src, width * texcomponents );
  1694.             dst += destTex->Width * texcomponents * sizeof(GLubyte);
  1695.             src += width * texcomponents * sizeof(GLubyte);
  1696.          }
  1697.          gl_free_texture_image(subTexImg);
  1698.       }
  1699.  
  1700.       /* if the image's reference count is zero, delete it now */
  1701.       if (image->RefCount==0) {
  1702.          gl_free_image(image);
  1703.       }
  1704.  
  1705.       texSet->Current2D->Dirty = GL_TRUE;
  1706.       ctx->Texture.AnyDirty = GL_TRUE;
  1707.  
  1708.       /* tell driver about change */
  1709.       if (ctx->Driver.TexSubImage) {
  1710.     (*ctx->Driver.TexSubImage)( ctx, GL_TEXTURE_2D, texSet->Current2D, level,
  1711.                     xoffset, yoffset, width, height,
  1712.                     texSet->Current2D->Image[level]->IntFormat,
  1713.                     destTex );
  1714.       }
  1715.       else {
  1716.     if (ctx->Driver.TexImage) {
  1717.       (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D, texSet->Current2D, level,
  1718.                    texSet->Current2D->Image[level]->IntFormat,
  1719.                    destTex );
  1720.     }
  1721.       }
  1722.    }
  1723.    else {
  1724.       /* if no image, an error must have occured, do more testing now */
  1725.       GLint components, size;
  1726.  
  1727.       if (width<0) {
  1728.          gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(width)" );
  1729.          return;
  1730.       }
  1731.       if (height<0) {
  1732.          gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(height)" );
  1733.          return;
  1734.       }
  1735.       if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
  1736.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(format)" );
  1737.          return;
  1738.       }
  1739.       components = gl_components_in_format( format );
  1740.       if (components<0 || format==GL_STENCIL_INDEX
  1741.           || format==GL_DEPTH_COMPONENT){
  1742.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(format)" );
  1743.          return;
  1744.       }
  1745.       size = gl_sizeof_type( type );
  1746.       if (size<=0) {
  1747.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(type)" );
  1748.          return;
  1749.       }
  1750.       /* if we get here, probably ran out of memory during unpacking */
  1751.       gl_error( ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D" );
  1752.    }
  1753. }
  1754.  
  1755.  
  1756.  
  1757. void gl_TexSubImage3DEXT( GLcontext *ctx,
  1758.                           GLenum target, GLint level,
  1759.                           GLint xoffset, GLint yoffset, GLint zoffset,
  1760.                           GLsizei width, GLsizei height, GLsizei depth,
  1761.                           GLenum format, GLenum type,
  1762.                           struct gl_image *image )
  1763. {
  1764.    struct gl_texture_set *texSet = &ctx->Texture.Set[ctx->Texture.CurrentSet];
  1765.    struct gl_texture_image *destTex;
  1766.  
  1767.    if (target!=GL_TEXTURE_3D_EXT) {
  1768.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(target)" );
  1769.       return;
  1770.    }
  1771.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  1772.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(level)" );
  1773.       return;
  1774.    }
  1775.  
  1776.    destTex = texSet->Current3D->Image[level];
  1777.    if (!destTex) {
  1778.       gl_error( ctx, GL_INVALID_OPERATION, "glTexSubImage3DEXT" );
  1779.       return;
  1780.    }
  1781.  
  1782.    if (xoffset < -((GLint)destTex->Border)) {
  1783.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(xoffset)" );
  1784.       return;
  1785.    }
  1786.    if (yoffset < -((GLint)destTex->Border)) {
  1787.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(yoffset)" );
  1788.       return;
  1789.    }
  1790.    if (zoffset < -((GLint)destTex->Border)) {
  1791.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(zoffset)" );
  1792.       return;
  1793.    }
  1794.    if (xoffset + width > (GLint) (destTex->Width+destTex->Border)) {
  1795.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(xoffset+width)" );
  1796.       return;
  1797.    }
  1798.    if (yoffset + height > (GLint) (destTex->Height+destTex->Border)) {
  1799.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(yoffset+height)" );
  1800.       return;
  1801.    }
  1802.    if (zoffset + depth  > (GLint) (destTex->Depth+destTex->Border)) {
  1803.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(zoffset+depth)" );
  1804.       return;
  1805.    }
  1806.  
  1807.    if (image) {
  1808.       /* unpacking must have been error-free */
  1809.       GLint texcomponents = components_in_intformat(destTex->Format);
  1810.       GLint dstRectArea = destTex->Width * destTex->Height;
  1811.       GLint srcRectArea = width * height;
  1812.  
  1813.       if (image->Type==GL_UNSIGNED_BYTE && texcomponents==image->Components) {
  1814.          /* Simple case, just byte copy image data into texture image */
  1815.          /* row by row. */
  1816.          GLubyte *dst = destTex->Data 
  1817.                + (zoffset * dstRectArea +  yoffset * destTex->Width + xoffset)
  1818.                * texcomponents;
  1819.          GLubyte *src = (GLubyte *) image->Data;
  1820.          GLint j, k;
  1821.          for(k=0;k<depth; k++) {
  1822.            for (j=0;j<height;j++) {
  1823.               MEMCPY( dst, src, width * texcomponents );
  1824.               dst += destTex->Width * texcomponents;
  1825.               src += width * texcomponents;
  1826.            }
  1827.            dst += dstRectArea * texcomponents * sizeof(GLubyte);
  1828.            src += srcRectArea * texcomponents * sizeof(GLubyte);
  1829.          }
  1830.       }
  1831.       else {
  1832.          /* General case, convert image pixels into texels, scale, bias, etc */
  1833.          struct gl_texture_image *subTexImg = image_to_texture(ctx, image,
  1834.                                         destTex->IntFormat, destTex->Border);
  1835.          GLubyte *dst = destTex->Data 
  1836.                + (zoffset * dstRectArea +  yoffset * destTex->Width + xoffset)
  1837.                * texcomponents;
  1838.          GLubyte *src = subTexImg->Data;
  1839.          GLint j, k;
  1840.          for(k=0;k<depth; k++) {
  1841.            for (j=0;j<height;j++) {
  1842.               MEMCPY( dst, src, width * texcomponents );
  1843.               dst += destTex->Width * texcomponents;
  1844.               src += width * texcomponents;
  1845.            }
  1846.            dst += dstRectArea * texcomponents * sizeof(GLubyte);
  1847.            src += srcRectArea * texcomponents * sizeof(GLubyte);
  1848.          }
  1849.          gl_free_texture_image(subTexImg);
  1850.       }
  1851.       /* if the image's reference count is zero, delete it now */
  1852.       if (image->RefCount==0) {
  1853.          gl_free_image(image);
  1854.       }
  1855.  
  1856.       texSet->Current3D->Dirty = GL_TRUE;
  1857.       ctx->Texture.AnyDirty = GL_TRUE;
  1858.  
  1859.       /* tell driver about change */
  1860.       if (ctx->Driver.TexImage) {
  1861.          (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_3D_EXT, texSet->Current3D,
  1862.                                   level, texSet->Current3D->Image[level]->IntFormat,
  1863.                   destTex );
  1864.       }
  1865.    }
  1866.    else {
  1867.       /* if no image, an error must have occured, do more testing now */
  1868.       GLint components, size;
  1869.  
  1870.       if (width<0) {
  1871.          gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(width)" );
  1872.          return;
  1873.       }
  1874.       if (height<0) {
  1875.          gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(height)" );
  1876.          return;
  1877.       }
  1878.       if (depth<0) {
  1879.          gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(depth)" );
  1880.          return;
  1881.       }
  1882.       if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
  1883.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(format)" );
  1884.          return;
  1885.       }
  1886.       components = components_in_intformat( format );
  1887.       if (components<0 || format==GL_STENCIL_INDEX
  1888.           || format==GL_DEPTH_COMPONENT){
  1889.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(format)" );
  1890.          return;
  1891.       }
  1892.       size = gl_sizeof_type( type );
  1893.       if (size<=0) {
  1894.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(type)" );
  1895.          return;
  1896.       }
  1897.       /* if we get here, probably ran out of memory during unpacking */
  1898.       gl_error( ctx, GL_OUT_OF_MEMORY, "glTexSubImage3DEXT" );
  1899.    }
  1900. }
  1901.  
  1902.  
  1903.  
  1904. /*
  1905.  * Read an RGBA image from the frame buffer.
  1906.  * Input:  ctx - the context
  1907.  *         x, y - lower left corner
  1908.  *         width, height - size of region to read
  1909.  *         format - one of GL_RED, GL_RGB, GL_LUMINANCE, etc.
  1910.  * Return: gl_image pointer or NULL if out of memory
  1911.  */
  1912. static struct gl_image *read_color_image( GLcontext *ctx, GLint x, GLint y,
  1913.                                           GLsizei width, GLsizei height,
  1914.                                           GLenum format )
  1915. {
  1916.    struct gl_image *image;
  1917.    GLubyte *imgptr;
  1918.    GLint components;
  1919.    GLint i, j;
  1920.  
  1921.    components = components_in_intformat( format );
  1922.  
  1923.    /*
  1924.     * Allocate image struct and image data buffer
  1925.     */
  1926.    image = (struct gl_image *) malloc( sizeof(struct gl_image) );
  1927.    if (image) {
  1928.       image->Width = width;
  1929.       image->Height = height;
  1930.       image->Depth = 1;
  1931.       image->Components = components;
  1932.       image->Format = format;
  1933.       image->Type = GL_UNSIGNED_BYTE;
  1934.       image->RefCount = 0;
  1935.       image->Data = (GLubyte *) malloc( width * height * components );
  1936.       if (!image->Data) {
  1937.          free(image);
  1938.          return NULL;
  1939.       }
  1940.    }
  1941.    else {
  1942.       return NULL;
  1943.    }
  1944.  
  1945.    imgptr = (GLubyte *) image->Data;
  1946.  
  1947.    /* Select buffer to read from */
  1948.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.ReadBuffer );
  1949.  
  1950.    for (j=0;j<height;j++) {
  1951.       GLubyte rgba[MAX_WIDTH][4];
  1952.       gl_read_rgba_span( ctx, width, x, y+j, rgba );
  1953.  
  1954.       switch (format) {
  1955.          case GL_ALPHA:
  1956.             for (i=0;i<width;i++) {
  1957.                *imgptr++ = rgba[i][ACOMP];
  1958.             }
  1959.             break;
  1960.          case GL_LUMINANCE:
  1961.             for (i=0;i<width;i++) {
  1962.                *imgptr++ = rgba[i][RCOMP];
  1963.             }
  1964.             break;
  1965.          case GL_LUMINANCE_ALPHA:
  1966.             for (i=0;i<width;i++) {
  1967.                *imgptr++ = rgba[i][RCOMP];
  1968.                *imgptr++ = rgba[i][ACOMP];
  1969.             }
  1970.             break;
  1971.          case GL_INTENSITY:
  1972.             for (i=0;i<width;i++) {
  1973.                *imgptr++ = rgba[i][RCOMP];
  1974.             }
  1975.             break;
  1976.          case GL_RGB:
  1977.             for (i=0;i<width;i++) {
  1978.                *imgptr++ = rgba[i][RCOMP];
  1979.                *imgptr++ = rgba[i][GCOMP];
  1980.                *imgptr++ = rgba[i][BCOMP];
  1981.             }
  1982.             break;
  1983.          case GL_RGBA:
  1984.             for (i=0;i<width;i++) {
  1985.                *imgptr++ = rgba[i][RCOMP];
  1986.                *imgptr++ = rgba[i][GCOMP];
  1987.                *imgptr++ = rgba[i][BCOMP];
  1988.                *imgptr++ = rgba[i][ACOMP];
  1989.             }
  1990.             break;
  1991.          default:
  1992.             gl_problem(ctx, "Bad format in read_color_image");
  1993.             break;
  1994.       } /*switch*/
  1995.  
  1996.    } /*for*/         
  1997.  
  1998.    /* Restore drawing buffer */
  1999.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DrawBuffer );
  2000.  
  2001.    return image;
  2002. }
  2003.  
  2004.  
  2005.  
  2006.  
  2007. void gl_CopyTexImage1D( GLcontext *ctx,
  2008.                         GLenum target, GLint level,
  2009.                         GLenum internalformat,
  2010.                         GLint x, GLint y,
  2011.                         GLsizei width, GLint border )
  2012. {
  2013.    GLint format;
  2014.    struct gl_image *teximage;
  2015.  
  2016.    if (INSIDE_BEGIN_END(ctx)) {
  2017.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexImage1D" );
  2018.       return;
  2019.    }
  2020.    if (target!=GL_TEXTURE_1D) {
  2021.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1D(target)" );
  2022.       return;
  2023.    }
  2024.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  2025.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage1D(level)" );
  2026.       return;
  2027.    }
  2028.    if (border!=0 && border!=1) {
  2029.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage1D(border)" );
  2030.       return;
  2031.    }
  2032.    if (width<2*border || width>2+MAX_TEXTURE_SIZE || width<0) {
  2033.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage1D(width)" );
  2034.       return;
  2035.    }
  2036.    format = decode_internal_format( internalformat );
  2037.    if (format<0 || (internalformat>=1 && internalformat<=4)) {
  2038.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage1D(format)" );
  2039.       return;
  2040.    }
  2041.  
  2042.    teximage = read_color_image( ctx, x, y, width, 1, (GLenum) format );
  2043.    if (!teximage) {
  2044.       gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D" );
  2045.       return;
  2046.    }
  2047.  
  2048.    gl_TexImage1D( ctx, target, level, internalformat, width,
  2049.                   border, GL_RGBA, GL_UNSIGNED_BYTE, teximage );
  2050.  
  2051.    /* teximage was freed in gl_TexImage1D */
  2052. }
  2053.  
  2054.  
  2055.  
  2056. void gl_CopyTexImage2D( GLcontext *ctx,
  2057.                         GLenum target, GLint level, GLenum internalformat,
  2058.                         GLint x, GLint y, GLsizei width, GLsizei height,
  2059.                         GLint border )
  2060. {
  2061.    GLint format;
  2062.    struct gl_image *teximage;
  2063.  
  2064.    if (INSIDE_BEGIN_END(ctx)) {
  2065.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexImage2D" );
  2066.       return;
  2067.    }
  2068.    if (target!=GL_TEXTURE_2D) {
  2069.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
  2070.       return;
  2071.    }
  2072.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  2073.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(level)" );
  2074.       return;
  2075.    }
  2076.    if (border!=0 && border!=1) {
  2077.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(border)" );
  2078.       return;
  2079.    }
  2080.    if (width<2*border || width>2+MAX_TEXTURE_SIZE || width<0) {
  2081.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(width)" );
  2082.       return;
  2083.    }
  2084.    if (height<2*border || height>2+MAX_TEXTURE_SIZE || height<0) {
  2085.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(height)" );
  2086.       return;
  2087.    }
  2088.    format = decode_internal_format( internalformat );
  2089.    if (format<0 || (internalformat>=1 && internalformat<=4)) {
  2090.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(format)" );
  2091.       return;
  2092.    }
  2093.  
  2094.    teximage = read_color_image( ctx, x, y, width, height, (GLenum) format );
  2095.    if (!teximage) {
  2096.       gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D" );
  2097.       return;
  2098.    }
  2099.  
  2100.    gl_TexImage2D( ctx, target, level, internalformat, width, height,
  2101.                   border, GL_RGBA, GL_UNSIGNED_BYTE, teximage );
  2102.  
  2103.    /* teximage was freed in gl_TexImage2D */
  2104. }
  2105.  
  2106.  
  2107.  
  2108.  
  2109. /*
  2110.  * Do the work of glCopyTexSubImage[123]D.
  2111.  * TODO: apply pixel bias scale and mapping.
  2112.  */
  2113. static void copy_tex_sub_image( GLcontext *ctx, struct gl_texture_image *dest,
  2114.                                 GLint width, GLint height,
  2115.                                 GLint srcx, GLint srcy,
  2116.                                 GLint dstx, GLint dsty, GLint zoffset )
  2117. {
  2118.    GLint i, j;
  2119.    GLint format, components, rectarea;
  2120.    GLint texwidth, texheight; 
  2121.  
  2122.    texwidth = dest->Width;
  2123.    texheight = dest->Height;
  2124.    rectarea = texwidth * texheight;
  2125.    zoffset *= rectarea; 
  2126.    format = dest->Format;
  2127.    components = components_in_intformat( format );
  2128.  
  2129.    /* Select buffer to read from */
  2130.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.ReadBuffer );
  2131.  
  2132.    for (j=0;j<height;j++) {
  2133.       GLubyte rgba[MAX_WIDTH][4];
  2134.       GLubyte *texptr;
  2135.  
  2136.       gl_read_rgba_span( ctx, width, srcx, srcy+j, rgba );
  2137.  
  2138.       texptr = dest->Data + ( zoffset + (dsty+j) * texwidth + dstx) * components;
  2139.  
  2140.       switch (format) {
  2141.          case GL_ALPHA:
  2142.             for (i=0;i<width;i++) {
  2143.                *texptr++ = rgba[i][ACOMP];
  2144.             }
  2145.             break;
  2146.          case GL_LUMINANCE:
  2147.             for (i=0;i<width;i++) {
  2148.                *texptr++ = rgba[i][RCOMP];
  2149.             }
  2150.             break;
  2151.          case GL_LUMINANCE_ALPHA:
  2152.             for (i=0;i<width;i++) {
  2153.                *texptr++ = rgba[i][RCOMP];
  2154.                *texptr++ = rgba[i][ACOMP];
  2155.             }
  2156.             break;
  2157.          case GL_INTENSITY:
  2158.             for (i=0;i<width;i++) {
  2159.                *texptr++ = rgba[i][RCOMP];
  2160.             }
  2161.             break;
  2162.          case GL_RGB:
  2163.             for (i=0;i<width;i++) {
  2164.                *texptr++ = rgba[i][RCOMP];
  2165.                *texptr++ = rgba[i][GCOMP];
  2166.                *texptr++ = rgba[i][BCOMP];
  2167.             }
  2168.             break;
  2169.          case GL_RGBA:
  2170.             for (i=0;i<width;i++) {
  2171.                *texptr++ = rgba[i][RCOMP];
  2172.                *texptr++ = rgba[i][GCOMP];
  2173.                *texptr++ = rgba[i][BCOMP];
  2174.                *texptr++ = rgba[i][ACOMP];
  2175.             }
  2176.             break;
  2177.       } /*switch*/
  2178.    } /*for*/         
  2179.  
  2180.  
  2181.    /* Restore drawing buffer */
  2182.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DrawBuffer );
  2183. }
  2184.  
  2185.  
  2186.  
  2187.  
  2188. void gl_CopyTexSubImage1D( GLcontext *ctx,
  2189.                               GLenum target, GLint level,
  2190.                               GLint xoffset, GLint x, GLint y, GLsizei width )
  2191. {
  2192.    struct gl_texture_set *texSet = &ctx->Texture.Set[ctx->Texture.CurrentSet];
  2193.    struct gl_texture_image *teximage;
  2194.  
  2195.    if (INSIDE_BEGIN_END(ctx)) {
  2196.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage1D" );
  2197.       return;
  2198.    }
  2199.    if (target!=GL_TEXTURE_1D) {
  2200.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" );
  2201.       return;
  2202.    }
  2203.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  2204.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage1D(level)" );
  2205.       return;
  2206.    }
  2207.    if (width<0) {
  2208.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage1D(width)" );
  2209.       return;
  2210.    }
  2211.  
  2212.    teximage = texSet->Current1D->Image[level];
  2213.  
  2214.    if (teximage) {
  2215.       if (xoffset < -((GLint)teximage->Border)) {
  2216.          gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage1D(xoffset)" );
  2217.          return;
  2218.       }
  2219.       /* NOTE: we're adding the border here, not subtracting! */
  2220.       if (xoffset+width > (GLint) (teximage->Width+teximage->Border)) {
  2221.          gl_error( ctx, GL_INVALID_VALUE,
  2222.                    "glCopyTexSubImage1D(xoffset+width)" );
  2223.          return;
  2224.       }
  2225.       if (teximage->Data) {
  2226.          copy_tex_sub_image( ctx, teximage, width, 1, x, y, xoffset, 0, 0 );
  2227.  
  2228.      /* tell driver about change */
  2229.      if (ctx->Driver.TexSubImage) {
  2230.        (*ctx->Driver.TexSubImage)( ctx, GL_TEXTURE_1D,
  2231.                        texSet->Current1D, level,
  2232.                        xoffset,0,width,1,
  2233.                        teximage->IntFormat,
  2234.                        teximage );
  2235.      }
  2236.      else {
  2237.        if (ctx->Driver.TexImage) {
  2238.          (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D, texSet->Current1D, level,
  2239.                       teximage->IntFormat,
  2240.                       teximage );
  2241.        }
  2242.      }
  2243.       }
  2244.    }
  2245.    else {
  2246.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage1D" );
  2247.    }
  2248. }
  2249.  
  2250.  
  2251.  
  2252. void gl_CopyTexSubImage2D( GLcontext *ctx,
  2253.                               GLenum target, GLint level,
  2254.                               GLint xoffset, GLint yoffset,
  2255.                               GLint x, GLint y, GLsizei width, GLsizei height )
  2256. {
  2257.    struct gl_texture_set *texSet = &ctx->Texture.Set[ctx->Texture.CurrentSet];
  2258.    struct gl_texture_image *teximage;
  2259.  
  2260.    if (INSIDE_BEGIN_END(ctx)) {
  2261.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D" );
  2262.       return;
  2263.    }
  2264.    if (target!=GL_TEXTURE_2D) {
  2265.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
  2266.       return;
  2267.    }
  2268.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  2269.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(level)" );
  2270.       return;
  2271.    }
  2272.    if (width<0) {
  2273.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(width)" );
  2274.       return;
  2275.    }
  2276.    if (height<0) {
  2277.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(height)" );
  2278.       return;
  2279.    }
  2280.  
  2281.    teximage = texSet->Current2D->Image[level];
  2282.  
  2283.    if (teximage) {
  2284.       if (xoffset < -((GLint)teximage->Border)) {
  2285.          gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(xoffset)" );
  2286.          return;
  2287.       }
  2288.       if (yoffset < -((GLint)teximage->Border)) {
  2289.          gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(yoffset)" );
  2290.          return;
  2291.       }
  2292.       /* NOTE: we're adding the border here, not subtracting! */
  2293.       if (xoffset+width > (GLint) (teximage->Width+teximage->Border)) {
  2294.          gl_error( ctx, GL_INVALID_VALUE,
  2295.                    "glCopyTexSubImage2D(xoffset+width)" );
  2296.          return;
  2297.       }
  2298.       if (yoffset+height > (GLint) (teximage->Height+teximage->Border)) {
  2299.          gl_error( ctx, GL_INVALID_VALUE,
  2300.                    "glCopyTexSubImage2D(yoffset+height)" );
  2301.          return;
  2302.       }
  2303.  
  2304.       if (teximage->Data) {
  2305.          copy_tex_sub_image( ctx, teximage, width, height,
  2306.                              x, y, xoffset, yoffset, 0 );
  2307.      /* tell driver about change */
  2308.      if (ctx->Driver.TexSubImage) {
  2309.        (*ctx->Driver.TexSubImage)( ctx, GL_TEXTURE_2D, texSet->Current2D, level,
  2310.                        xoffset, yoffset, width, height,
  2311.                        teximage->IntFormat,
  2312.                        teximage );
  2313.      }
  2314.      else {
  2315.        if (ctx->Driver.TexImage) {
  2316.          (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D, texSet->Current2D, level,
  2317.                       teximage->IntFormat,
  2318.                       teximage );
  2319.        }
  2320.      }
  2321.       }
  2322.    }
  2323.    else {
  2324.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D" );
  2325.    }
  2326. }
  2327.  
  2328.  
  2329.  
  2330. void gl_CopyTexSubImage3DEXT( GLcontext *ctx,
  2331.                               GLenum target, GLint level,
  2332.                               GLint xoffset, GLint yoffset, GLint zoffset,
  2333.                               GLint x, GLint y, GLsizei width, GLsizei height )
  2334. {
  2335.    struct gl_texture_set *texSet = &ctx->Texture.Set[ctx->Texture.CurrentSet];
  2336.    struct gl_texture_image *teximage;
  2337.  
  2338.    if (INSIDE_BEGIN_END(ctx)) {
  2339.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage3DEXT" );
  2340.       return;
  2341.    }
  2342.    if (target!=GL_TEXTURE_2D) {
  2343.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3DEXT(target)" );
  2344.       return;
  2345.    }
  2346.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  2347.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(level)" );
  2348.       return;
  2349.    }
  2350.    if (width<0) {
  2351.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(width)" );
  2352.       return;
  2353.    }
  2354.    if (height<0) {
  2355.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(height)" );
  2356.       return;
  2357.    }
  2358.  
  2359.    teximage = texSet->Current3D->Image[level];
  2360.    if (teximage) {
  2361.       if (xoffset < -((GLint)teximage->Border)) {
  2362.          gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(xoffset)" );
  2363.          return;
  2364.       }
  2365.       if (yoffset < -((GLint)teximage->Border)) {
  2366.          gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(yoffset)" );
  2367.          return;
  2368.       }
  2369.       if (zoffset < -((GLint)teximage->Border)) {
  2370.          gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(zoffset)" );
  2371.          return;
  2372.       }
  2373.       /* NOTE: we're adding the border here, not subtracting! */
  2374.       if (xoffset+width > (GLint) (teximage->Width+teximage->Border)) {
  2375.          gl_error( ctx, GL_INVALID_VALUE,
  2376.                    "glCopyTexSubImage3DEXT(xoffset+width)" );
  2377.          return;
  2378.       }
  2379.       if (yoffset+height > (GLint) (teximage->Height+teximage->Border)) {
  2380.          gl_error( ctx, GL_INVALID_VALUE,
  2381.                    "glCopyTexSubImage3DEXT(yoffset+height)" );
  2382.          return;
  2383.       }
  2384.       if (zoffset > (GLint) (teximage->Depth+teximage->Border)) {
  2385.          gl_error( ctx, GL_INVALID_VALUE,
  2386.                    "glCopyTexSubImage3DEXT(zoffset+depth)" );
  2387.          return;
  2388.       }
  2389.  
  2390.       if (teximage->Data) {
  2391.          copy_tex_sub_image( ctx, teximage, width, height, 
  2392.                              x, y, xoffset, yoffset, zoffset);
  2393.  
  2394.      /* tell driver about change */
  2395.      if (ctx->Driver.TexImage) {
  2396.        (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_3D_EXT, texSet->Current3D,
  2397.                     level, teximage->IntFormat,
  2398.                     teximage );
  2399.      }
  2400.       }
  2401.    }
  2402.    else {
  2403.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage3DEXT" );
  2404.    }
  2405. }
  2406.  
  2407.